//go:build !notmpfiles
// +build !notmpfiles

// Package collector 包含所有用于收集和导出系统指标的单独收集器。
package collector

import (
	"fmt"
	"log/slog"
	"os"
	"regexp"
	"strconv"
	"strings"
)

// ParseArcconfPdLog 解析 arcconf 日志文件并提取磁盘信息
func ParseArcconfPdLog(filename string, logger *slog.Logger) ([]DiskInfo, error) {
	// 读取文件数据
	data, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("读取 arcconf 日志失败: %w", err)
	}

	content := string(data)
	// 使用正则表达式查找设备块
	deviceRegex := regexp.MustCompile(`Device #(\d+)`)
	deviceMatches := deviceRegex.FindAllStringSubmatchIndex(content, -1)

	disks := make([]DiskInfo, 0)

	// 遍历所有匹配的设备
	for i, match := range deviceMatches {
		if len(match) < 4 {
			continue
		}

		// 确定设备块的范围
		start := match[0] // 设备编号的开始位置
		end := len(content)
		if i+1 < len(deviceMatches) {
			end = deviceMatches[i+1][0] // 下一个设备的开始位置
		}

		// 提取设备块内容
		deviceBlock := content[start:end]
		deviceID := "Device #" + content[match[2]:match[3]] // 提取设备编号

		// 创建磁盘信息结构
		disk := DiskInfo{
			DeviceID:    deviceID,
			Controller:  "controller0", // 在实际实现中，您将从日志中提取此信息
			ErrorCounts: make(map[string]int),
		}

		// 使用正则表达式查找所有错误计数器
		// 支持两种格式：
		// 1. "xxx Error Count : value" (原始格式)
		// 2. "xxx Errors : value" (新格式)
		// 3. "xxx Failure Count : value" (原始格式)
		// 4. "xxx Failures : value" (新格式)
		// 5. "xxx Warning Count : value" (原始格式)
		// 6. "xxx Warnings : value" (新格式)
		errorRegex := regexp.MustCompile(`([A-Za-z0-9 ]+(?:Error Count|Errors|Failure Count|Failures|Warning Count|Warnings))\s*:\s*(\d+)`)
		//fmt.Println(errorRegex)

		errorMatches := errorRegex.FindAllStringSubmatch(deviceBlock, -1)

		// 提取所有错误计数器
		for _, errorMatch := range errorMatches {
			if len(errorMatch) >= 3 {
				// 清理错误类型名称，去除多余空格
				errorType := strings.TrimSpace(errorMatch[1])
				errorCount, _ := strconv.Atoi(errorMatch[2])

				// 标准化错误类型名称
				standardErrorType := standardizeErrorType(errorType)
				disk.ErrorCounts[standardErrorType] = errorCount
			}
		}

		disks = append(disks, disk)
	}

	// 返回磁盘信息和空错误
	return disks, nil
}

// standardizeErrorType 标准化错误类型名称
func standardizeErrorType(errorType string) string {
	// 移除末尾的复数形式，统一为单数形式
	switch {
	case strings.HasSuffix(errorType, " Errors"):
		return strings.TrimSuffix(errorType, " Errors") + " Error Count"
	case strings.HasSuffix(errorType, " Failures"):
		return strings.TrimSuffix(errorType, " Failures") + " Failure Count"
	case strings.HasSuffix(errorType, " Warnings"):
		return strings.TrimSuffix(errorType, " Warnings") + " Warning Count"
	default:
		return errorType
	}
}

// ParseArcconfLogicDiskLog 解析 arcconf 逻辑磁盘日志文件并提取逻辑磁盘信息
func ParseArcconfLogicDiskLog(filename string, logger *slog.Logger) ([]LogicDiskInfo, error) {
	// 读取文件数据
	data, err := os.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("读取 arcconf 逻辑磁盘日志失败: %w", err)
	}

	content := string(data)

	// 使用正则表达式查找逻辑设备块
	logicDeviceRegex := regexp.MustCompile(`Logical Device number\s+(\d+)`)
	deviceMatches := logicDeviceRegex.FindAllStringSubmatchIndex(content, -1)

	disks := make([]LogicDiskInfo, 0)

	// 遍历所有匹配的逻辑设备
	for i, match := range deviceMatches {
		if len(match) < 4 {
			continue
		}

		// 确定逻辑设备块的范围
		start := match[0] // 逻辑设备编号的开始位置
		end := len(content)
		if i+1 < len(deviceMatches) {
			end = deviceMatches[i+1][0] // 下一个逻辑设备的开始位置
		}

		// 提取逻辑设备块内容
		deviceBlock := content[start:end]
		deviceID := "Logical Device " + content[match[2]:match[3]] // 提取逻辑设备编号

		// 创建逻辑磁盘信息结构
		disk := LogicDiskInfo{
			DeviceID:   deviceID,
			Controller: "controller0", // 在实际实现中，您将从日志中提取此信息
			Info:       make(map[string]string),
		}

		// 查找 RAID 级别
		raidLevelRegex := regexp.MustCompile(`RAID level\s*:\s*(\d+)`)
		if raidLevelMatch := raidLevelRegex.FindStringSubmatch(deviceBlock); len(raidLevelMatch) >= 2 {
			disk.RaidLevel = "RAID" + raidLevelMatch[1]
		}

		// 查找磁盘大小
		sizeRegex := regexp.MustCompile(`Size\s*:\s*([\d\s]+MB)`)
		if sizeMatch := sizeRegex.FindStringSubmatch(deviceBlock); len(sizeMatch) >= 2 {
			disk.Size = strings.TrimSpace(sizeMatch[1])
		}

		// 查找状态 (改进的正则表达式，避免跨行匹配)
		//statusRegex := regexp.MustCompile(`Status of Logical Device\s*:\s*(\w*)`)
		statusRegex := regexp.MustCompile(`Status of Logical Device\s*:\s*(\w*)`)

		//if statusMatch := statusRegex.FindStringSubmatch(deviceBlock); len(statusMatch) >= 2 {
		//	fmt.Println(statusMatch[0])
		//
		//	fmt.Println(statusMatch[1])
		//	disk.State = strings.TrimSpace(statusMatch[1])
		//}
		// 处理逻辑
		if statusMatch := statusRegex.FindStringSubmatch(deviceBlock); len(statusMatch) >= 2 {
			rawStatus := statusMatch[1]
			// 判断是否包含干扰文本，包含则标记为 unknown
			if strings.Contains(rawStatus, "Additional") {
				disk.State = "unknown"
			} else {
				disk.State = strings.TrimSpace(rawStatus)
			}
			fmt.Println("匹配到的完整行：", statusMatch[0])
			fmt.Println("最终状态：", disk.State)
		}

		// 查找物理磁盘数量
		//devicesRegex := regexp.MustCompile(`Device\s+(\d+)`)
		devicesRegex := regexp.MustCompile(`(Device|Segment)\s+(\d+)`)
		devicesMatch := devicesRegex.FindAllStringSubmatch(deviceBlock, -1)
		disk.NumberOfDrives = len(devicesMatch)

		// 如果没有找到设备，尝试另一种方式查找物理磁盘数量
		if disk.NumberOfDrives == 0 {
			numDrivesRegex := regexp.MustCompile(`Array Physical Device Information.*?Device ID.*?\n(?:\s*Device \d+.*?\n)+`)
			if numDrivesMatch := numDrivesRegex.FindString(deviceBlock); numDrivesMatch != "" {
				deviceCountRegex := regexp.MustCompile(`Device \d+`)
				devices := deviceCountRegex.FindAllString(numDrivesMatch, -1)
				disk.NumberOfDrives = len(devices)
			}
		}

		disks = append(disks, disk)
	}

	return disks, nil
}
